from aiohttp import web, WSMsgType
import asyncio

class WebSocket(object):
    '''
    WebScoket 类
    '''
    def __init__(self, global_sensor = None):

        self.virtual_wharf = global_sensor

    def build_aiv_init_infos(self):
        aiv_init_infos = self.virtual_wharf.aiv_init_infos
        '''
        aiv_infos 是所有无人车的当前位置，结构如下
        [
            {
                'id' 
                'battary' 
                'status' 
                'capacity' 
                'taskid' 
                'position' 
            },
            ...
        ]
        '''
        aiv_infos = {
            "type": "AIV",
            "AIVlist": aiv_init_infos
        }
        return aiv_infos

    def build_aiv_update_infos(self):
        aiv_infos = self.virtual_wharf.aiv_infos
        '''
        aiv_infos 是所有无人车的当前位置，结构如下
        [
            {
                'id' 
                'battary' 
                'status' 
                'capacity' 
                'taskid' 
                'position' 
            },
            ...
        ]
        '''
        aiv_infos = {
            "type": "updateAIV",
            "AIVlist": aiv_infos
        }
        return aiv_infos

    def build_aiv_tracks(self):
        aiv_paths = self.virtual_wharf.aiv_paths
        '''
        aiv_paths 是当前所有正在运动的车辆，要走的轨迹，用来画线，里面的结构是
        [
            {
                "AIVid": aiv_id,
                "Pointarr": []
            },
            {
                "AIVid": aiv_id,
                "Pointarr": []
            },
            {
                "AIVid": aiv_id,
                "Pointarr": []
            },
            ...
        ]
        '''
        aiv_paths = {
            "type": "Scheduledpath",
            "AIVlist": aiv_paths
        }
        # for track in aiv_paths:
        #     track["type"] = "Scheduledpath"
        return aiv_paths

    async def ws_connection(self, request):
        # websocket 对象
        ws = web.WebSocketResponse()
        # 等待用户连接
        await ws.prepare(request)
        # 将此次连接添加到 app['websockets'] 中，便于安全的释放
        request.app['websockets'].append(ws)
        print('a websocket client connected')
        # 获取当前所有无人车的所有信息
        aiv_infos = self.build_aiv_init_infos()
        await ws.send_json(aiv_infos)
        # 获取正在运行的无人车路径
        aiv_paths = self.build_aiv_tracks()
        await ws.send_json(aiv_paths)

        # 运行到这里会阻塞，可以理解为一个循环，一直等待前端传 msg 过来
        # 目前前端会定时发一个 ping 信号过来
        async for msg in ws:
            if msg.type == WSMsgType.TEXT:
                # 在这里看到前端发送了什么
                # print(msg.data)
                if msg.data == 'close':
                    await ws.close()
                else:
                    # 进入循环，向客户端发送消息
                    while True:
                        await asyncio.sleep(0.1)
                        # 发送所有AIV的当前坐标位置
                        positions = self.build_aiv_update_infos()
                        await ws.send_json(positions)
                        # 发送当前最新发生的事件
                        # await self.send_events(ws)

            elif msg.type == WSMsgType.ERROR:
                print('websocket收到了错误消息：%s' % ws.exception())

        # 断开连接
        print('websocket 会话结束')
        return ws

    async def send_events(self, ws):
        events = self.virtual_wharf.events
        '''
        所有最近（不会太久远）发生的事件，结构如下
        [
            {
                'time': 事件发生的时间,
                'type': 事件类型,
                'detail': 事件的具体细节信息
            },
            {
                'time': 事件发生的时间,
                'type': 事件类型,
                'detail': 事件的具体细节信息
            },
            ...
        ]
        '''
        '''
        可以在这里继续包裹一层外壳数据
        '''
        if events:
            await ws.send_json({
                'type': 'event',
                'events': events
            })